package com.google.code.fulltank;

import com.google.code.fulltank.price.FuelPriceHistory;
import com.google.code.fulltank.strategy.FuelingStrategy;
import com.google.code.fulltank.usage.FuelUsageHistory;
import org.joda.time.LocalDate;

/**
 * Simulates a given combination of fueling strategy, fuel prices and usage
 * histories.
 *
 * @author DL
 */
public class FuelingSimulator {

    public static class FuelingStats {
        public int numFills = 0;
        public double cost = 0;
    }

    public static FuelingStats simulate(
        FuelTank tank, FuelPriceHistory prices, FuelUsageHistory usage,
        FuelingStrategy strategy) {
        
        FuelingStats stats = new FuelingStats();

        LocalDate date = usage.getFirstDate();
        LocalDate lastDate = usage.getLastDate();

        if (prices.getFirstDate().isAfter(date)) {
            throw new IllegalStateException("Usage and price history mismatch");
        }

        LocalDate lastPriceDate = prices.getFirstDate();
        double price = prices.getUpdatedFuelPrice(lastPriceDate);

        while (!date.isAfter(lastDate)) {
            while (lastPriceDate.isBefore(date)) {
                lastPriceDate = lastPriceDate.plusDays(1);
                Double newPrice = prices.getUpdatedFuelPrice(lastPriceDate);
                if (newPrice != null) {
                    price = newPrice;
                }
            }

            double amountToFill = strategy.onDate(date);
            if (amountToFill > 0) {
                amountToFill = tank.fill(amountToFill);
                ++stats.numFills;
                stats.cost += (amountToFill * price);
            }

            tank.burn(usage.getFuelUsage(date));
            date = date.plusDays(1);
        }

        return stats;
    }
}
